<?php
/**
 * TinyMVC - TinyMVCException.class.php file
 * 
 * @author Adrian Wieczorek <adi(at)tinymvc(dot)org>
 * @author Piotr Szymanski <bufoor(at)bluearrow(dot)org>
 * @package TinyMVC
 * @version $Id: TinyMVCException.class.php 3 2007-09-11 12:08:07Z adi3ek $
 * 
 */
 
/**
 * core framework exception class
 * @package TinyMVC
 */
class TinyMVCException extends Exception {
  
	private $backtrace;
  
	public function __construct($message, $code = 0) {
		parent::__construct($message, $code);
		$this->backtrace = $this->getTrace();
	}
  
	/**
	 * display full html exception trace page
	 * @return string exception page
	 */
	private function getHtmlTrace() { 	
		header('Content-Type: text/html; charset=utf-8');
		echo '<style type="text/css"> 
												body { margin-top:5px;	padding:0px; font-family:verdana, arial, helvetica, sans-serif; font-size: 11px; color:#000000;	background:white; }  									
												div.err_border {border: 1px solid black; margin: 2px; background: #f4f4f4;}
												div.err_line {padding: 2px; color: gray;}
												div.err_error {padding: 2px; color:red; font-size: 12pt; }
												div.err_arg {padding-left: 30px; font-size: 8pt; font-family: Courier New; color: black;}
												div.err_source {font-size: 10pt; font-family: Courier New; padding: 5px; color: blue;}
									</style>';
									
		echo '<hr>';
		echo '<body>';
		echo '<div class="err_error"><b>ERROR: '.get_class($this).'</b>:  '.$this->getMessage().'<br /><br /><b>FILE:</b> '.$this->getFile().'  <b>LINE:</b> '.$this->getLine().'</div><br />'; 
		if(count($this->backtrace)) {
   foreach($this->backtrace as $item) {
				$html .= '<div class="err_border">';
				$html .= "<div class=\"err_line\"><b>file:</b> ".$item['file'].'</div>';
				$html .= "<div class=\"err_line\"><b>line:</b> ".$item['line'].'</div>';
				$html .= "<div class=\"err_line\"><b>function:</b> ".$item['function'].'</div>';
				$html .= '<div class="err_line"><b>class:</b> '.$item['class'].'</div>';
				$html .= '<div class="err_line"><b>type:</b> '.$item['type'].'</div>';
				if(count($item['args'])) {
					$html .= '<div class="err_line"><b>args:</b></div>';
					$html .= "<pre>";
					foreach($item['args'] as $key=>$agr) {
						$html .= '<div class="err_arg">['.$key.'] => '.print_r($agr,true).'</div>';
					}
					$html .= "</pre>";				
				}
				$source = $this->dumpSource($item['file'], $item['line']);
				if($source) {
					$html .= '<div class="err_line"><b>source:</b>';
					$html .= '<div class="err_source">';
					$html .= $source;
					$html .= '</div>';
					$html .= '</div>';
				}
				$html .= '</div><br />';  
				echo $html;
   }
		}
		echo '</body>';
 }

 /**
  * handle exception
  */
 public function handleException() {
		$this->getHtmlTrace();
 }
    
	private function dumpSource($file, $line) {
 
		$source = explode("\n", file_get_contents($file, true));
		$result = '';
		for ($index=$line-4; $index<=$line+4; $index++) {
			$result	.=	"<span>$index</span>: ";
			$result	.=	trim(str_replace(' ', '&nbsp;', htmlentities($source[$index-1])));
			$result	.=	"<br />\n";
  }
  return $result;
	} 
}
